package com.oauth2.client.config;

import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.stereotype.Controller;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

@Configuration
// @PropertySource({ "classpath:com/lwl/config/upload.properties" })

@ComponentScan(basePackages = { "com.oauth2.client.dao", "com.oauth2.client.service" }, excludeFilters = @ComponentScan.Filter({
		Controller.class, RestController.class }))
// 导入SpringSecurity配置
//@Import(SecurityConfiguration.class)

public class RootContextConfig {

	Logger log = Logger.getLogger("lwl");
	Logger schedulingLogger = Logger.getLogger("lwlTask");
	// 读取properties文件
	// @Autowired
	// private Environment environment;

	// json需要用到
	@Bean
	public ObjectMapper objectMapper() {
		/*
		 * System.out.println(environment.getProperty("location"));
		 * System.out.println(environment.getProperty("maxFileSize"));
		 * System.out.println(environment.getProperty("maxRequestSize"));
		 * System.out.println(environment.getProperty("fileSizeThreshold"));
		 */
		ObjectMapper mapper = new ObjectMapper();
		mapper.findAndRegisterModules();
		mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);

		return mapper;
	}

	// xml需要用到,一定要保证所有的xml注解可以被扫描到
	@Bean
	public Jaxb2Marshaller jaxb2Marshaller() {
		Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
		marshaller.setPackagesToScan(new String[] { "com.lwl" });
		return marshaller;
	}

	/** 设置国际化资源位置 */
	@Bean
	public MessageSource messageSource() {
		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
		messageSource.setCacheSeconds(-1);
		messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
		messageSource.setBasenames("/WEB-INF/i18n/titles", "/WEB-INF/i18n/messages", "/WEB-INF/i18n/errors",
				"/WEB-INF/i18n/validation");
		return messageSource;
	}

	// bean验证提供者
	@Bean
	public LocalValidatorFactoryBean localValidatorFactoryBean() {
		LocalValidatorFactoryBean validatorFactory = new LocalValidatorFactoryBean();
		// 设置验证器的提供者,默认Spring会自己寻找类路径上的提供者
		validatorFactory.setProviderClass(HibernateValidator.class);
		validatorFactory.setValidationMessageSource(this.messageSource());
		return validatorFactory;
	}

	/**
	 * 为了支持方法参数和返回值的验证,使用MethodValidationPostProcessor
	 * 代理被验证方法的执行,默认的将使用类路径上的验证提供者,不包含messageSource
	 * MethodValidationPostProcessor将寻找标注了
	 * (org.springframework.validation.annotation.Validated;
	 * javax.validation.executable.ValidateOnExecution;)的类.并为他们创建代理,
	 * 这样被标注参数上的参数验证才会在方法之前执行,被标注方法上的返回值验证才可以在方法执行后执行
	 */
	@Bean
	public MethodValidationPostProcessor methodValidationPostProcessor() {
		MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
		processor.setValidator(this.localValidatorFactoryBean());
		return processor;
	}

}
